
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>

#ifndef WIN32
#define _wtoi(ws) wcstol(ws, NULL, 2)
#endif        

inline bool IsWhiteSpace(wchar_t c)
{
	return (iswspace(wint_t(c)) != 0);
}

inline bool IsAlpha(wchar_t c)
{
	return (iswalpha(wint_t(c)) != 0);
}

inline bool IsDigit(wchar_t c)
{
	return (iswdigit(wint_t(c)) != 0);
}

inline bool IsHexDigit(wchar_t c)
{
	return (iswxdigit(wint_t(c)) != 0);
}

inline int DecDigitValue(wchar_t c)
{
	wchar_t wszBuffer[2];
	wszBuffer[0] = c;
	wszBuffer[1] = 0;
	return _wtoi(wszBuffer);
}

inline int HexDigitValue(wchar_t c)
{
	wchar_t wszBuffer[2];
	wszBuffer[0] = c;
	wszBuffer[1] = 0;
	int nNbr = 0;
	swscanf(wszBuffer, L"%x", &nNbr);
	return nNbr;
}

inline bool IsAlphaDigit(wchar_t c)
{
	return (iswalpha(wint_t(c)) || iswdigit(wint_t(c)));
}

inline bool IsAlphaDigitEx(wchar_t c)
{
    return(IsAlphaDigit(c) || c == wchar_t('_') || c == wchar_t('.') || c == wchar_t(':') || c == wchar_t('-'));
}

inline bool IsXMLCharacter(wchar_t c)
{
	if (iswcntrl(wint_t(c)) == false)
		return true;
	if (c == wchar_t('\r') || c == wchar_t('\n') || c == wchar_t('\t'))
		return true;
	return false;
}



int ParseWhiteSpace(const wchar_t *pbuf,int len)
{
	int c = 0;
	const wchar_t *p = pbuf;	
	if (IsWhiteSpace(*p) == false)
	{		
		return 0;
	}
	do
	{
		p++;
		c++;
	} while (IsWhiteSpace(*p) == true);
	return c;
}

int ParseWChar(const wchar_t *pbuf,const wchar_t c)
{
	if (*pbuf != c)
	{
		return 0;
	}
	return 1;
}

int ParseString(const char *pbuf,int len,const char *pstr)
{
	const char *p = pbuf;
	const char *psub = pstr;
	int c = 0;
	while (*psub)
	{		
		if (*p != *psub)
		{
			return -1;			
		}
		p++;psub++;c++;
		if(c > len)
			return -1;
	}
	return c;
}

int ParseDecNumber(const wchar_t *pbuf,int len,int& nNbr)
{
	const wchar_t *p = pbuf;
	int c = 0;
	if (IsDigit(*p) == false)
		return -1;
	nNbr = 0;
	do
	{
		wchar_t wszBuffer[2];
		wszBuffer[0] = *p;
		wszBuffer[1] = 0;
		int nTemp = _wtoi(wszBuffer);
		nNbr = (nNbr * 10) + DecDigitValue(*p);
		p++;
		c++;
		if(c >= len)
			break;
	} while (IsDigit(*p) == true);	
	return c;
}

int ParseHexNumber(const wchar_t *pbuf,int len,int& nNbr)
{
	const wchar_t *p = pbuf;
	int c = 0;
	
	if (IsHexDigit(*p) == false)
		return false;
	nNbr = 0;
	do
	{
		nNbr = (nNbr * 16) + HexDigitValue(*p);
		p++;
		c++;
		if(c >= len)
			break;
	} while (IsHexDigit(*p) == true);
	
	return c;
}

int ParseStringInsensitive(const wchar_t *pbuf,int len,const wchar_t *pstr)
{
	const wchar_t *p = pbuf;
	const wchar_t *psub = pstr;
	int c = 0;
	while (*psub)
	{
//		if (_totupper((wint_t)*p) != _totupper((wint_t)*psub))
		if (_toupper((wint_t)*p) != _toupper((wint_t)*psub))
		{
			return -1;			
		}
		p++;
		c++;psub++;
		if(c >= len)
			return -1;
	}
	return c;
}

int SkipComment(const char **ppbuf,int len)
{
	const char *p = *ppbuf;
	const char * s;

	int c = 0;

	if((c = ParseString(p,len-c,"<!--")) > 0)
	{
		s = strstr(p,"-->");//find host name
		if(s == NULL)
			return -1;
		s+=4;
		c = s - p;
		*ppbuf = s;

		return c;
	}

	return 0;  //no comment
}
